import { Client, Wallet as XrplWallet, xrpToDrops } from "xrpl";
import { BridgeConfigType } from "../config.type";

// Setup the signer list on the door account
async function setupSignerList(client: Client, bridgeDoorWallet: XrplWallet, witnesses: string[], claimThreshold: number) {
    const signerListSet = await client.autofill({
        TransactionType: "SignerListSet",
        Account: bridgeDoorWallet.address,
        SignerQuorum: claimThreshold,
        SignerEntries: witnesses.map((w) => ({
            SignerEntry: {
                Account: w,
                SignerWeight: 1,
            },
        })),
    });
    // sign transaction
    const signed = bridgeDoorWallet.sign(signerListSet);
    await client.submit(signed.tx_blob);
}

// Send a create bridge transaction on xrpl door account
async function createBridge(client: Client, bridgeDoorWallet: XrplWallet, minAccountCreate: number, signatureReward: number) {
    // Hardcoded for now, should be the address of the evm contract, but
    const issuerAddress = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
    const createBridge = await client.autofill({
        TransactionType: "XChainCreateBridge",
        Account: bridgeDoorWallet.address,
        XChainBridge: {
            LockingChainDoor: bridgeDoorWallet.address,
            LockingChainIssue: {
                currency: "XRP",
            },
            // IssuingChainDoor: evmAddressToXrplAccount(evmContractAddress),
            IssuingChainDoor: issuerAddress,
            IssuingChainIssue: {
                currency: "XRP",
            },
        },
        MinAccountCreateAmount: xrpToDrops(minAccountCreate),
        SignatureReward: xrpToDrops(signatureReward),
    });
    // sign transaction
    const signed = bridgeDoorWallet.sign(createBridge);
    const result = await client.submit(signed.tx_blob);
    if (result.result.engine_result === "tesSUCCESS") {
    } else {
        console.log("Error creating bridge", result);
    }
}

async function fundXrpAccount(client: Client, senderSeed: string, destinationAddress: string, amount: number): Promise<void> {
    const funder = XrplWallet.fromSeed(senderSeed);
    const fundTransaction = await client.autofill({
        TransactionType: "Payment",
        Account: funder.address,
        Destination: destinationAddress,
        Amount: xrpToDrops(amount),
    });
    // sign transaction
    const signed = funder.sign(fundTransaction);
    const result = await client.submit(signed.tx_blob);
    if (result.result.engine_result === "tesSUCCESS") {
    } else {
        console.log("Error creating bridge", result);
    }
}

export async function CreateXrpBridge(config: BridgeConfigType): Promise<string> {
    const client = new Client(config.xrplRpc);
    await client.connect();

    for (const witness of config.witnesses) {
        await fundXrpAccount(client, config.xrplSeed, witness.xrpAddress, 100);
    }
    const xrpDoorWallet = XrplWallet.generate();
    await fundXrpAccount(client, config.xrplSeed, xrpDoorWallet.address, 100);
    await setupSignerList(
        client,
        xrpDoorWallet,
        config.witnesses.map((w) => w.xrpAddress),
        config.quorum,
    );
    await createBridge(client, xrpDoorWallet, config.minCreateAmount, config.minRewardAmount);

    return xrpDoorWallet.address;
}
